package org.road0329.dlt698.asn1.axdr;

import org.road0329.dlt698.ReverseByteArrayInputStream;
import org.road0329.dlt698.ReverseByteArrayOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class AxdrLength {
    private static Logger logger = LoggerFactory.getLogger(AxdrLength.class);
    private int length;

    public AxdrLength(int length) {
        this.length = length;
    }

    public static int encodeLength(ReverseByteArrayOutputStream output, int length) {
        int codeLength = 0;
        if (length == 0) {
            output.write(0);
            codeLength++;
        } else {
            int lengthOfLength = 0;
            for (int i = 0; (length >> 8 * i) != 0; i++) {
                output.write((length >> 8 * i) & 0xff);
                lengthOfLength++;
                codeLength++;
            }
            if (length >= 128) {
                output.write((lengthOfLength & 0xff) | 0x80);
                codeLength++;
            }
        }
        return codeLength;
    }

    public byte[] encodeLengthBuf(int length) {
        if (length == 0) {
            return new byte[]{0};
        } else {
            int lengthOfLength = 1;
            while ((length >> (8 * lengthOfLength)) != 0) {
                lengthOfLength++;
            }
            int offset = 0;
            byte[] buffer;
            if (length > 255) {
                buffer = new byte[lengthOfLength + 1];
                buffer[0] = (byte) (lengthOfLength | 0x80);
                offset++;
            } else {
                buffer = new byte[lengthOfLength];
            }
            for (int i = 0; i < lengthOfLength; i++) {
                buffer[offset + i] = (byte) (length >> (8 * (lengthOfLength - 1 - i)));
            }
            return buffer;
        }
    }

    public int decode(ReverseByteArrayInputStream input) throws Exception {
        int codeLength = 0;
        this.length = input.read();
        codeLength++;
        if ((this.length & 0x80) == 0x80) {
            int encodedLength = this.length ^ 0x80;
            codeLength += encodedLength;
            this.length = 0;
            byte[] byteCode = new byte[encodedLength];
            try {
                if (input.read(byteCode, 0, encodedLength) < encodedLength) {
                    throw new Exception("Error Decoding AxdrLength");
                }
            } catch (IOException e) {
                logger.info("Error Decoding AxdrLength.", e);
                throw new Exception("Error Decoding AxdrLength");
            }
            for (int i = 0; i < encodedLength; i++) {
                this.length |= (byteCode[i] & 0xff) << (8 * (encodedLength - i - 1));
            }
        }
        return codeLength;
    }

    public int getValue() {
        return this.length;
    }

    public int encode(ReverseByteArrayOutputStream output) throws Exception {
        return AxdrLength.encodeLength(output, this.length);
    }
}

// Note: ReverseByteArrayOutputStream and ReverseByteArrayInputStream are not standard Java classes.
// You will need to implement these classes or use equivalent functionality from a library.



